#ifndef __C_NGISDATA_UDXKERNEL_H__
#define __C_NGISDATA_UDXKERNEL_H__

#include "IUdxKernel.h"

namespace NGIS
{
	namespace Data
	{
		class CUdxNode;
		class CUdxKernel : public IUdxKernel
		{
		public:
			CUdxKernel(EKernelType pType, const CUdxNode* pNode);

			~CUdxKernel();

		public:
			virtual const IUdxNode* getNode();

			virtual EKernelType getType();

		protected:
			friend class CUdxNode;
			const CUdxNode*					mNode;
			EKernelType							mType;
		};

		//////////////////////////////////////////////////////////////////////////

		class CUdxKernelIntValue : public CUdxKernel
		{
		public:
			CUdxKernelIntValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode), mValue(0)
			{ }

		public:
			virtual bool setTypedValue(int pValue);

			virtual int getTypedValue();

		private:
			int mValue;
		};

		class CUdxKernelRealValue : public CUdxKernel
		{
		public:
			CUdxKernelRealValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode), mValue(0.0)
			{ }

		public:
			virtual bool setTypedValue(double pValue);

			virtual double getTypedValue();

		private:
			double mValue;
		};

		class CUdxKernelStringValue : public CUdxKernel
		{
		public:
			CUdxKernelStringValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode), mValue("")
			{ }

		public:
			virtual bool setTypedValue(std::string pValue);

			virtual std::string getTypedValue();

		private:
			std::string mValue;
		};

		class CUdxKernelVector2dValue : public CUdxKernel
		{
		public:
			CUdxKernelVector2dValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool setTypedValue(double pX, double pY);

			virtual Vector2d getTypedValue();

			virtual void getTypedValue(double& pX, double& pY);
		private:
			Vector2d mValue;
		};

		class CUdxKernelVector3dValue : public CUdxKernel
		{
		public:
			CUdxKernelVector3dValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool setTypedValue(double pX, double pY, double pZ);

			virtual Vector3d getTypedValue();

			virtual void getTypedValue(double& pX, double& pY, double& pZ);
		private:
			Vector3d mValue;
		};

		class CUdxKernelVector4dValue : public CUdxKernel
		{
		public:
			CUdxKernelVector4dValue(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool setTypedValue(double pX, double pY, double pZ, double pM);

			virtual Vector4d getTypedValue();

			virtual void getTypedValue(double& pX, double& pY, double& pZ, double& pM);
		private:
			Vector4d mValue;
		};

		//////////////////////////////////////////////////////////////////////////

		class CUdxKernelIntArray : public CUdxKernel
		{
		public:
			CUdxKernelIntArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(int pValue);

			virtual bool getTypedValueByIndex(int idx, int& val);

			virtual bool setTypedValue(int pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<int>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<int> mValueList;
		};

		class CUdxKernelRealArray : public CUdxKernel
		{
		public:
			CUdxKernelRealArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(double pValue);

			virtual bool getTypedValueByIndex(int idx, double& val);

			virtual bool setTypedValue(double pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<double>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<double> mValueList;
		};

		class CUdxKernelStringArray : public CUdxKernel
		{
		public:
			CUdxKernelStringArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(std::string pValue);

			virtual bool getTypedValueByIndex(int idx, std::string& val);

			virtual bool setTypedValue(std::string pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<std::string>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<std::string> mValueList;
		};

		class CUdxKernelVector2dArray : public CUdxKernel
		{
		public:
			CUdxKernelVector2dArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(double pX, double pY);

			virtual bool getTypedValueByIndex(int idx, Vector2d& val);

			virtual bool getTypedValueByIndex(int idx, double& pX, double& pY);

			virtual bool setTypedValue(Vector2d pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<Vector2d>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<Vector2d> mValueList;
		};

		class CUdxKernelVector3dArray : public CUdxKernel
		{
		public:
			CUdxKernelVector3dArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(double pX, double pY, double pZ);

			virtual bool getTypedValueByIndex(int idx, Vector3d& val);

			virtual bool getTypedValueByIndex(int idx, double& pX, double& pY, double& pZ);

			virtual bool setTypedValue(Vector3d pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<Vector3d>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<Vector3d> mValueList;
		};

		class CUdxKernelVector4dArray : public CUdxKernel
		{
		public:
			CUdxKernelVector4dArray(EKernelType pType, const CUdxNode* pNode)
				: CUdxKernel(pType, pNode)
			{ }

		public:
			virtual bool addTypedValue(double pX, double pY, double pZ, double pM);

			virtual bool getTypedValueByIndex(int idx, Vector4d& val);

			virtual bool getTypedValueByIndex(int idx, double& pX, double& pY, double& pZ, double& pM);

			virtual bool setTypedValue(Vector4d pValue, int idx);

			virtual int getCount() { return mValueList.size(); }

			virtual void clearValue() { mValueList.clear(); }

			virtual bool removeValueByIndex(int idx) 
			{
				if (idx<0 || idx>=mValueList.size())
					return false;
				std::vector<Vector4d>::iterator it = mValueList.begin();
				it = it + idx;
				mValueList.erase(it);
				return true;
			}
		private:
			std::vector<Vector4d> mValueList;
		};

	}
}

#endif